<!--
 * Tencent is pleased to support the open source community by making BK-JOB生物智算平台 available.
 *
 * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
 *
 * BK-JOB生物智算平台 is licensed under the MIT License.
 *
 * License for BK-JOB生物智算平台:
 *
 *
 * Terms of the MIT License:
 * ---------------------------------------------------
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
 * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
 * the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
-->

<template>
  <jb-form
    ref="form"
    fixed
    :label-width="110"
    :model="formData">
    <item-factory
      field="jobName"
      :form-data="formData"
      name="scriptName"
      :placeholder="$t('推荐按步骤实际处理的场景行为来取名')"
      @on-change="handleChange" />
    <item-factory
      content-field="content"
      :form-data="formData"
      language-field="scriptLanguage"
      name="scriptSourceOfTemplate"
      script-id-field="scriptId"
      script-source-field="scriptSource"
      script-status-field="status"
      script-version-id-field="scriptVersionId"
      @on-change="handleChange"
      @on-reset="handleScriptContentReset"
      @reset-slurm="resetSlurm" />

    <item-factory
      v-show="false"
      content-field="content"
      :form-data="formData"
      language-field="scriptLanguage"
      name="scriptContent"
      script-source-field="scriptSource"
      :script-variables="scriptVariables"
      @on-change="handleChange" />
    <item-factory
      v-if="formData.scriptSource == 1"
      content-field="scriptCommand"
      :form-data="formData"
      language-field="scriptLanguage"
      name="scriptCommand"
      script-source-field="scriptSource"
      :script-variables="scriptVariables"
      @on-change="handleChange" />
    <item-factory
      content-field="content"
      :form-data="formData"
      language-field="scriptLanguage"
      name="scriptCommandOfTemplate"
      script-id-field="scriptId"
      script-source-field="scriptSource"
      script-status-field="status"
      script-version-id-field="scriptVersionId"
      @on-change="handleChange"
      @on-reset="handleScriptContentReset"
      @reset-slurm="resetSlurm" />
    <item-factory
      :form-data="formData"
      name="scriptParam"
      param-field="scriptParam"
      secure-field="secureParam"
      @on-change="handleChange" />
    <item-factory
      field="timeout"
      :form-data="formData"
      name="scriptTimeout"
      @on-change="handleChange" />
    <item-factory
      field="ignoreError"
      :form-data="formData"
      name="errorHandle"
      @on-change="handleChange" />
    <item-factory
      field="account"
      :form-data="formData"
      name="scriptAccount"
      script-language-field="scriptLanguage"
      @on-change="handleChange" />
    <item-factory
      field="executeTarget"
      :form-data="formData"
      name="executeTargetOfTemplate"
      :variable="variable"
      @on-change="handleChange" />
  </jb-form>
</template>
<script>

  import { Base64 } from 'js-base64';

  import TaskStepModel from '@model/task/task-step';
  import TaskHostNodeModel from '@model/task-host-node';

  import {   analysisCommand,
             genDefaultName,
             genDefaultWorkDir,
             scriptErrorConfirm,
             sTc,
             timeToSeconds } from '@utils/assist';

  import ItemFactory from '@components/task-step/script/item-factory';

  const getSlurmParam = () => ({
    baseInfo: '', // 其他基本信息
    command: genDefaultWorkDir(), // 任务脚本路径
    scriptCommand: '',
    userId: 'root', // 默认root 页面可选择slurm 用户
    partition: window.PROJECT_CONFIG.SCOPE_ID_NAME, // 队列分区 单分区无需指定 多分区需指定具体队列
    nodes: 1, // 计算节点 单节点无需指定 多计算节点需要指定 不超过当前计算节点上限
    numCpus: 0, // CPU核数
    numGpus: 0, // GPU个数
    gpuType: '', // GPU类型
    timeLimit: '', // 计算最长时间限制
    logPath: `${genDefaultWorkDir()}logs/${genDefaultName()}`, // 指定任务的保存路径地址
    workSpaceScriptType: 'bash', // 脚本类型
  });

  const getDefaultData = () => ({
    isScriptContentLoading: false,

    // 错误处理
    ignoreError: 0,
    // 脚本步骤的id
    id: -1,
    // 删除标记
    delete: 0,
    // 需要升级
    status: 0,
    // 脚本来源类型 1-本地脚本 2-引用脚本 3-引用公共脚本
    scriptSource: TaskStepModel.scriptStep.TYPE_SOURCE_LOCAL,
    // 引用的脚本 ID
    scriptId: '',
    // 引用脚本的版本 ID
    scriptVersionId: '',
    // 脚本内容的类型语言，默认shell
    scriptLanguage: 1,
    // 脚本内容
    content: '',
    // 脚本参数
    scriptParam: '',
    // 超时时间
    timeout: 7200,
    // 敏感参数 （0-关闭 1-开启）
    secureParam: 0,
    // 执行账号
    account: '',
    // 执行目标信息 （主机和全局变量二选一）
    executeTarget: new TaskHostNodeModel({}),

    jobName: '', // 脚本步骤名称
    /**  新增参数  */
    ...getSlurmParam(),
  });

  export default {
    name: '',
    components: {
      ItemFactory,
    },
    inheritAttrs: false,
    props: {
      data: {
        type: Object,
        default: () => ({}),
      },
      variable: {
        type: Array,
        default: () => [],
      },
      scriptVariables: {
        type: Array,
        default: () => [],
      },
      stepName: {
        type: Array,
        default: () => [],
      },
    },
    data() {
      return {
        formData: getDefaultData(),
      };
    },
    watch: {
      data: {
        handler(newData) {
          // 本地新建的步骤id为-1，已提交后端保存的id大于0
          // console.log('3、', newData)
          const scriptParam = analysisCommand(newData.scriptParam, newData.scriptSource);
          this.formData = Object.assign({}, this.formData, newData, this.convertKeysToCamelCase(newData.params || {}), scriptParam);
          console.log(' this.formData **====',  this.formData);

          // 同步 jobName 的时间戳

          // 有数据需要自动验证一次
          if (newData.id) {
            setTimeout(() => {
              this.$refs.form.validate();
            });
          }
        },
        immediate: true,
      },
    },
    mounted() {
      window.IPInputScope = 'SCRIPT_EXECUTE';
      this.$once('hook:beforeDestroy', () => {
        window.IPInputScope = '';
      });
      this.formData.scriptParam = this.createNewContent().ncontent;
    },
    methods: {
      resetSlurm() {
        this.formData = Object.assign({}, this.formData, getSlurmParam());
      },
      handleChange(field, value) {
        this.formData[field] = value;

        if (field == 'jobName') this.formData.logPath = `${genDefaultWorkDir()}logs/${value}.log`;

        if (['scriptCommand', 'command', 'jobName', 'numCpus', 'numGpus', 'gpuType', 'timeLimit', 'userId', 'nodes', 'partition', 'logPath'].indexOf(field) != -1) {
          this.formData.scriptParam = this.createNewContent().ncontent;
        }
      },
      handleScriptContentReset(payload) {
        this.formData = {
          ...this.formData,
          ...payload,
        };
      },
      createNewContent() {
        const { cTs } = this;
        const { scriptCommand, command, jobName, numCpus = 0, numGpus = 0, gpuType = '', timeLimit, userId, nodes = 0, logPath, partition = '', workSpaceScriptType } = this.formData;
        const nCommand = this.formData.scriptSource == 1 ? Base64.decode(scriptCommand)?.replace(/"/g, '\'') : command;
        // console.log('---', this.formData)
        const ncontent = `--command "${nCommand}" --${cTs('jobName')} "${jobName}" --${cTs('partition')} "${partition}"  --${cTs('numCpus')} ${numCpus} --${cTs('numGpus')} ${numGpus} --${cTs('gpuType')} "${gpuType}" --${cTs('timeLimit')} "${this.formatTime(timeLimit)}" --${cTs('userId')} "${userId}" --${cTs('nodes')} ${nodes} --${cTs('logPath')} "${logPath}" `;

        return {
          ncontent,
          params: {
            [`${cTs('command')}`]: nCommand,
            [`${cTs('jobName')}`]: jobName,
            [`${cTs('numCpus')}`]: parseInt(numCpus),
            [`${cTs('numGpus')}`]: parseInt(numGpus),
            [`${cTs('gpuType')}`]: gpuType,
            [`${cTs('timeLimit')}`]: timeLimit,
            [`${cTs('userId')}`]: userId,
            [`${cTs('nodes')}`]: parseInt(nodes),
            [`${cTs('logPath')}`]: logPath,
            [`${cTs('partition')}`]: partition,
            [`${cTs('workSpaceScriptType')}`]: workSpaceScriptType,
          },
        };
      },
      // handleScriptContentReset(payload) {
      //   this.formData = {
      //     ...this.formData,
      //     ...payload,
      //   };
      // },
      submit() {
        const {
          name,
          id,
          ignoreError,
          scriptParam,
          timeout,
          secureParam,
          scriptSource,
          scriptId,
          content,
          account,
          status,
          scriptVersionId,
          scriptLanguage,
          executeTarget,
          jobName,
        } = this.formData;

        const result = {
          id,
          name: jobName,
          delete: this.formData.delete,
          type: 1,
          scriptStepInfo: {
            ignoreError,
            scriptParam,
            timeout,
            scriptSource,
            scriptId,
            account,
            content,
            scriptLanguage,
            status,
            scriptVersionId,
            executeTarget,
            secureParam,
          },
        };

        if (scriptSource != 1) {
          result.name = this.formData.jobName;
          result.slurm = { ...this.createNewContent() };
        }

        return this.$refs.form.validate()
          .then(() => true, () => false)
          .then(validate => scriptErrorConfirm().then(() => {
            // console.log(result, validate)
            this.$emit('on-change', result, validate);
          }));
      },
      cTs(str) {
        return str.replace(/([A-Z])/g, match => `_${match.toLowerCase()}`);
      },
      convertKeysToCamelCase(obj) {
        const newObj = {};
        for (const key in obj) {
          if (obj.hasOwnProperty(key)) {
            const newKey = sTc(key);
            if (key == 'timeLimit') {
              newObj[newKey] = timeToSeconds(obj[key]);
            } else {
              newObj[newKey] = obj[key];
            }
          }
        }
        return newObj;
      },
      formatTime(seconds) {
        // 计算小时、分钟和秒数
        const hours = Math.floor(seconds / 3600);
        const minutes = Math.floor((seconds % 3600) / 60);
        const secs = seconds % 60;

        // 格式化为两位数
        const formattedTime = [
          hours.toString().padStart(2, '0'),
          minutes.toString().padStart(2, '0'),
          secs.toString().padStart(2, '0'),
        ].join(':');

        return formattedTime;
      },
    },
  };
</script>
